#include <Eigen/Dense>
#include <Eigen/Sparse>

#include <iostream>


using namespace Eigen;
using namespace std;



// solve linear equations
void solveLinearLeastEquation(const Eigen::SparseMatrix<double> & LeftM, const Eigen::MatrixXd & RightM, 
	Eigen::MatrixXd & newVertices) 
{
	Eigen::SimplicialLLT<Eigen::SparseMatrix<double > > solver(LeftM.transpose() * LeftM);
	assert(solver.info() == Eigen::Success);
	newVertices = solver.solve(LeftM.transpose() * RightM).eval();
}


// get sparse weight matrix
void getWeightMatrix(const Eigen::VectorXd & weightVec, double originUniformWeight , double LaplacianWeightRate,
	Eigen::SparseMatrix<double, RowMajor> & weightM)
{

	Eigen::VectorXd weightVecUniform = weightVec / (weightVec.maxCoeff()) * LaplacianWeightRate * originUniformWeight;
	std::cout << "Vector size: " << weightVecUniform.size() <<endl;


	typedef Eigen::Triplet<double> TypeTriDouble;
	std::vector<TypeTriDouble> weightTripletList;
	weightTripletList.reserve(weightVecUniform.size());

	for (int i = 0; i < weightVecUniform.size(); ++i) {
		weightTripletList.push_back( TypeTriDouble(i,i, weightVecUniform(i)) );
	}

	std::cout << "Triplet size: " << weightTripletList.size() << endl;

	weightM.setFromTriplets(weightTripletList.begin(), weightTripletList.end());

	std::cout << "Convert weightVector to weightMatrix" << endl;
}